#include <cstdlib>
#include <cstdio>
#include <fstream>
#include <sstream>
#include <algorithm>

#include "OrzFile.h"
#include "zui.h"

using namespace std;
using namespace dataStructureZ;
using namespace dataStructureZ::DirTableZ;

#	define INDUP2 'w'
#	define INDDW2 's'
#	define INDLF2 'a'
#	define INDRG2 'd'

#	define INDUP3 'W'
#	define INDDW3 'S'
#	define INDLF3 'A'
#	define INDRG3 'D'

#if defined(__ANDROID__)
#	define INDUP '2'
#	define INDDW '8'
#	define INDLF '4'
#	define INDRG '6'
#	define INDEN '5'
static inline void whiteLine(void)
{
	cout<<white("___________________________________________________________________")<<endl;
}
static inline void logo(void)
{
	cout<<gray("_______");cout<<white("oooooo");cout<<gray("______________________");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("______________________")<<endl;
	cout<<gray("_____");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_");cout<<red("ooooooo");cout<<gray("_____");cout<<white("ooo");cout<<gray("____");cout<<white("ooo");cout<<gray("__");cout<<white("oooooo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("ooooo");cout<<gray("____")<<endl;
	cout<<gray("____");cout<<white("oo");cout<<gray("________");cout<<white("oo");cout<<gray("_");cout<<white("ooo");cout<<gray("_______");cout<<red("oo");cout<<gray("______");cout<<white("oooo");cout<<gray("__");cout<<white("oooo");cout<<gray("_");cout<<white("oo");cout<<gray("____");cout<<white("oo");cout<<gray("_");cout<<white("ooo");cout<<gray("____");cout<<white("oo");cout<<gray("___")<<endl;
	cout<<gray("____");cout<<white("oo");cout<<gray("________");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_______");cout<<red("oo");cout<<gray("_______");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_____");cout<<white("oooo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("___")<<endl;
	cout<<gray("____");cout<<white("oo");cout<<gray("________");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("______");cout<<red("oo");cout<<gray("________");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("_");cout<<white("oooo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("___")<<endl;
	cout<<gray("_____");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_____");cout<<red("oo");cout<<gray("_________");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("___");cout<<white("ooo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("___")<<endl;
	cout<<gray("_______");cout<<white("oooooo");cout<<gray("____");cout<<white("oo");cout<<gray("____");cout<<red("ooooooo");cout<<gray("_____");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("___");cout<<white("ooo");cout<<gray("_");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("___")<<endl;
	whiteLine();
}
static inline void tip(void)
{
	whiteLine();
	cout<<"Press \""<<INDUP<<"\" to switch previous index; \""<<INDDW<<"\" to switch next index;\n      \""<<INDRG<<"\" to open a index;          \""<<INDLF<<"\" to go back"<<endl;
}

#else
#	define INDUP '8'
#	define INDDW '2'
#	define INDLF '4'
#	define INDRG '6'
#	define INDEN '5'
static inline void whiteLine(void)
{
	cout<<white("____________________________________________________________________________________________________")<<endl;
}
static inline void logo(void)
{
	cout<<gray("_______");cout<<white("oooooo");cout<<gray("______________________");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("_______________________________________________________")<<endl;
	cout<<gray("_____");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_");cout<<red("ooooooo");cout<<gray("_____");cout<<white("ooo");cout<<gray("____");cout<<white("ooo");cout<<gray("__");cout<<white("oooooo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("ooooo");cout<<gray("___");cout<<white("oooooo");cout<<gray("___");cout<<white("oooo");cout<<gray("_");cout<<white("oo");cout<<gray("____");cout<<white("oooo");cout<<gray("____");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_")<<endl;
	cout<<gray("____");cout<<white("oo");cout<<gray("________");cout<<white("oo");cout<<gray("_");cout<<white("ooo");cout<<gray("_______");cout<<red("oo");cout<<gray("______");cout<<white("oooo");cout<<gray("__");cout<<white("oooo");cout<<gray("_");cout<<white("oo");cout<<gray("____");cout<<white("oo");cout<<gray("_");cout<<white("ooo");cout<<gray("____");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("____");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("___");cout<<white("oo");cout<<gray("___");cout<<white("oo");cout<<gray("____");cout<<white("oo");cout<<gray("__");cout<<white("ooo");cout<<gray("___")<<endl;
	cout<<gray("____");cout<<white("oo");cout<<gray("________");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_______");cout<<red("oo");cout<<gray("_______");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_____");cout<<white("oooo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("_____");cout<<white("oooo");cout<<gray("__");cout<<white("ooooo");cout<<gray("___");cout<<white("oooooooooo");cout<<gray("_");cout<<white("oo");cout<<gray("____")<<endl;
	cout<<gray("____");cout<<white("oo");cout<<gray("________");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("______");cout<<red("oo");cout<<gray("________");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("_");cout<<white("oooo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("_");cout<<white("oooo");cout<<gray("__");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_");cout<<white("ooo");cout<<gray("__");cout<<white("oo");cout<<gray("_________");cout<<white("oo");cout<<gray("____")<<endl;
	cout<<gray("_____");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("_____");cout<<red("oo");cout<<gray("_________");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("___");cout<<white("ooo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("___");cout<<white("ooo");cout<<gray("_");cout<<white("oo");cout<<gray("____");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("____");cout<<white("oo");cout<<gray("__");cout<<white("oo");cout<<gray("____")<<endl;
	cout<<gray("_______");cout<<white("oooooo");cout<<gray("____");cout<<white("oo");cout<<gray("____");cout<<red("ooooooo");cout<<gray("_____");cout<<white("oo");cout<<gray("______");cout<<white("oo");cout<<gray("___");cout<<white("ooo");cout<<gray("_");cout<<white("oo");cout<<gray("_");cout<<white("oo");cout<<gray("_____");cout<<white("oo");cout<<gray("___");cout<<white("ooo");cout<<gray("_");cout<<white("oo");cout<<gray("__");cout<<white("oooooo");cout<<gray("_____");cout<<white("oooo");cout<<gray("____");cout<<white("oo");cout<<gray("____")<<endl;
	whiteLine();
}
static inline void tip(void)
{
	whiteLine();
	cout<<"Press \""<<INDUP<<"\" to switch previous index; \""<<INDDW<<"\" to switch next index; \""<<INDRG<<"\" to open a index;    \""<<INDLF<<"\" to go back"<<endl;
}

#endif

#if !defined(_WINDOWS_) && !defined(__WIN32)
#	define stricmp(x, y) strcasecmp((x), (y))
#endif


template<class numerType> static inline string toString(numerType x)
{
	string result;
	stringstream sst;
	sst<<x;
	sst>>result;
	return result;
}

static inline string spc(int n)
{
	string s("");
	for(int i=0 ; i<n ; ++i)
		s += ' ';
	return s;
}

static inline bool makeUserSure(const char* optName, const char* optObjName = nullptr)
{
	size_t selectedIndex = 0;
	char keyInput;
	
	while(true)
	{
		cls;
		logo();
		
		cout<<"Are you sure to "<<optName;
		if(optObjName != nullptr)
			cout<<" \""<<optObjName<<"\"";
		cout<<"?"<<endl;
		
		if(selectedIndex == 0)
		#if defined(__ANDROID__)
			cout<<backWhite("    No                                                             ")<<endl;	
		#else
			cout<<backWhite("    No                                                                                              ")<<endl;
		#endif
		else          cout<<"    No"<<endl;
		
		if(selectedIndex == 1)
		#if defined(__ANDROID__)
			cout<<backWhite("    Yes                                                            ")<<endl;
		#else
			cout<<backWhite("    Yes                                                                                             ")<<endl;
		#endif
		else          cout<<"    Yes"<<endl;
		
		tip();
		
		switch(keyInput = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex < 1)
					++selectedIndex;
				else selectedIndex = 0;
			break;
			
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > 0)
					--selectedIndex;
				else selectedIndex = 1;
			break;
			
			case INDLF:case INDLF2:case INDLF3:
				return false;
			break;
			
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':case ' ':
				return selectedIndex==1? true : false;
			break;
		}
	}
}

enum MakeSureOption
{
	yes, no, cancel
};

static inline enum MakeSureOption makeUserSure_Triple(const char* optName, const char* optObjName = nullptr)
{
	size_t selectedIndex = 0;
	char keyInput;
	
	while(true)
	{
		cls;
		logo();
		
		cout<<"Are you sure to "<<optName;
		if(optObjName != nullptr)
			cout<<" \""<<optObjName<<"\"";
		cout<<"?"<<endl;
		
		if(selectedIndex == 0)
		#if defined(__ANDROID__)
			cout<<backWhite("    Cancel                                                         ")<<endl;	
		#else
			cout<<backWhite("    Cancel                                                                                          ")<<endl;
		#endif
		else          cout<<"    Cancel"<<endl;
		
		if(selectedIndex == 1)
		#if defined(__ANDROID__)
			cout<<backWhite("    Yes                                                            ")<<endl;
		#else
			cout<<backWhite("    Yes                                                                                             ")<<endl;
		#endif
		else          cout<<"    Yes"<<endl;
		
		if(selectedIndex == 2)
		#if defined(__ANDROID__)
			cout<<backWhite("    No                                                             ")<<endl;
		#else
			cout<<backWhite("    No                                                                                              ")<<endl;
		#endif
		else          cout<<"    No"<<endl;
		
		tip();
		
		switch(keyInput = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex < 2)
					++selectedIndex;
				else selectedIndex = 0;
			break;
			
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > 0)
					--selectedIndex;
				else selectedIndex = 2;
			break;
			
			case INDLF:case INDLF2:case INDLF3:
				return cancel;
			break;
			
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':case ' ':
				switch(selectedIndex)
				{
					case 0:return cancel;
					case 1:return yes;
					case 2:return no;
				}
			break;
		}
	}
}

static inline bool nameChk(const string& name)
{
	static const char* illeagleChr = "\\/:*?\"<>|";
	for(int i=0 ; i<9 ; ++i)
	{
		if(name.find(illeagleChr[i]) != string::npos)
			return false;
	}
	return true;
}

static inline string reNameMenu(const char* tips = nullptr)
{
	string newName("");
	
	do
	{
		if(newName != "")
		{
			cls;
			logo();
			cout<<endl<<endl;
			cout<<red("    File(Directory) name is not allowed contain these character:");
			cout<<" \\ / : * ? \" < > |"<<endl<<endl;
			whiteLine();
			cout<<yellow("Press Enter Key to continue...");
			cin.get();
		}
		cls;
		logo();
		if(tips != nullptr)
			cout<<tips;
		cout<<endl<<endl<<endl<<endl<<"    Input a new name:"<<endl;
		
		GOTOXY(0, 16);
		whiteLine();
		cout<<red("(Input nothing & Press Enter Key ---> go back.)");
		#if defined(__ANDROID__)
			box(22, 11, 45, 1, White);
		#else
			box(22, 11, 78, 1, White);
		#endif
		getline(cin, newName);
	}	while(newName!="" && !nameChk(newName));
	
	return newName;
}

static inline void viewAll(DirTable* nowAt)
{
	if(nowAt != nullptr)
	{
		cls;
		logo();
		cout<<"All files and directories:"<<endl<<endl;
		//cout<<*nowAt;
		nowAt->viewAll_current();
		#if defined(__ANDROID__)
			cout<<"===============================< END >============================="<<endl;
		#else
			cout<<"==============================================< END >==============================================="<<endl;
		#endif
		whiteLine();
		cout<<"Press any key to continue...";
		getch();
	}
}

typedef enum
{
	selectType_directory,
	selectType_file,
	selectType_directory_and_file
}	fsSelector_selectType_t;

#if defined(_WINDOWS_) || defined(_WIN32)
#include <Windows.h>

static inline deque<string> getDiskAreas(void)
{
	deque<string> list;
	DWORD bufferSize = GetLogicalDriveStrings(0, NULL);
	char *const buffer = new char[bufferSize];
	GetLogicalDriveStrings(bufferSize, buffer);
	for
	(
		ptrdiff_t i=0; 
		buffer[i] != '\0';
		i += (strlen(buffer+i)+1)
	)	list.push_back(buffer+i);
	
	delete buffer;
	return list;
}

static inline string selectDiskMenu(void)
{
	static const deque<string> list(getDiskAreas());
	
	char keyInput;
	
	size_t selectedIndex = 0;
	size_t idx;
	
	while(true)
	{
		cls;
		logo();
		
		cout<<"Select a Disk:"<<endl;
		
		idx=0; for
		(
			deque<string>::const_iterator i=list.begin();
			i != list.end();
			++i, ++idx
		)
		{
			if(idx == selectedIndex)
			{
				cout<<backWhite("    <DSK> ");
				cout<<draw(*i, bgWhite);
				cout<<draw(spc(90-(*i).length()),bgWhite)<<endl;
			}	else cout<<"    <DSK> "<<*i<<endl;
		}
		
		tip();
		
		switch(keyInput = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex+1 < list.size())
					++selectedIndex;
				else selectedIndex = 0;
			break;
			
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > 0)
					--selectedIndex;
				else selectedIndex = list.size()-1;
			break;
			
			case INDLF:case INDLF2:case INDLF3:
				return "";
			break;
			
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':case ' ':
			{
				string path = *(list.begin() + selectedIndex);
				return path.substr(0, path.length()-1);
			}
			break;
		}
	}
	return "";
}

static inline string fileSystemSelector
(fsSelector_selectType_t selectType = selectType_file)
{
	string path;
	
	deque<string> dirs;
	deque<string> files;
	size_t idx;
	stack<size_t> selIdxs;
	stack<string> stkPaths;
	
	char keyInput;
	
	while((path = selectDiskMenu()) != "")
	{
		stkPaths.push(path);
		size_t selectedIndex = 0;
		while(!stkPaths.empty())
		{
			intptr_t	aDIR;
			_finddata_t	aItem;
			
			aDIR = _findfirst(string(path + sSEP + "*.*").c_str(), &aItem);
					
			if(aDIR == -1) return "";
			
			dirs.clear();
			if(selectType != selectType_directory)
				files.clear();
			do
			{
				if(strcmp(aItem.name,  ".") && strcmp(aItem.name,  ".."))
				{
					if(aItem.attrib & _A_SUBDIR)
						dirs.push_back(aItem.name);
					else if(selectType != selectType_directory) files.push_back(aItem.name);
				}
			}	while(_findnext(aDIR, &aItem) == 0);
			
			size_t indexesCount = dirs.size()+files.size();
			if(selectedIndex > indexesCount)
				selectedIndex = indexesCount-1;
				
			while(true)
			{
				cls;
				logo();
				
				switch(selectType)
				{
					case selectType_directory:
						cout<<"Press Space Key to select current location:"<<endl;
					break;
					case selectType_file:
						cout<<"Select a file and press Space Key to confirm:"<<endl;
					break;
					case selectType_directory_and_file:
						cout<<"Select a directory or file and press Space Key to confirm:"<<endl;
					break;
				}
				
				idx = 0;
				for
				(
					deque<string>::const_iterator i = dirs.begin();
					i != dirs.end();
					++i, ++idx
				)
				{
					if(idx == selectedIndex)
					{
						cout<<backWhite("    <DIR> ");
						cout<<draw(*i, bgWhite);
						cout<<draw(spc(90 - (*i).length()), bgWhite)<<endl;
					}	else cout<<"    <DIR> "<<*i<<endl;
				}
				
				if(selectType != selectType_directory) for
				(
					deque<string>::const_iterator i = files.begin();
					i != files.end();
					++i, ++idx
				)
				{
					if(idx == selectedIndex)
					{
						cout<<backWhite("    <FIL> ");
						cout<<draw(*i, bgWhite);
						cout<<draw(spc(90 - (*i).length()), bgWhite)<<endl;
					}	else cout<<"    <FIL> "<<*i<<endl;
				}
				
				tip();
				
				switch(keyInput = getch())
				{
					case INDDW:case INDDW2:case INDDW3:
						if(selectedIndex+1 < indexesCount)
							++selectedIndex;
						else selectedIndex = 0;
					break;
					
					case INDUP:case INDUP2:case INDUP3:
						if(selectedIndex > 0)
							--selectedIndex;
						else selectedIndex = selectType == selectType_directory? dirs.size()-1 : indexesCount-1;
					break;
					
					case INDLF:case INDLF2:case INDLF3:
						path = path.substr(0, path.length() - stkPaths.top().length() - 1);
						stkPaths.pop();
						
						if(!selIdxs.empty())
						{
							selectedIndex = selIdxs.top();
							selIdxs.pop();
						}	else selectedIndex = 0;
						goto innerWhile;
					break;
					
					case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':
						if(selectedIndex < dirs.size())
						{
							stkPaths.push(*(dirs.begin() + selectedIndex));
							path = path + sSEP + stkPaths.top();
							selIdxs.push(selectedIndex);
							selectedIndex = 0;
							goto innerWhile;
						}
						else
						{
							path = path + sSEP + *(files.begin() + selectedIndex - dirs.size());
							_findclose(aDIR);
							return path;
						}
					break;
					
					case ' ':
						switch(selectType)
						{
							case selectType_directory:
								_findclose(aDIR);
								return path;
							break;
							case selectType_file:
								if(selectedIndex >= dirs.size())
								{
									path = path + sSEP + *(files.begin() + selectedIndex - dirs.size());
									_findclose(aDIR);
									return path;
								}
								else
								{
									stkPaths.push(*(dirs.begin() + selectedIndex));
									path = path + sSEP + stkPaths.top();
									selIdxs.push(selectedIndex);
									selectedIndex = 0;
									goto innerWhile;
								}
							break;
							case selectType_directory_and_file:
								if(selectedIndex < dirs.size())
								{
									path = path + sSEP + *(dirs.begin() + selectedIndex);
									_findclose(aDIR);
									return path;
								}
								else
								{
									path = path + sSEP + *(files.begin() + selectedIndex - dirs.size());
									_findclose(aDIR);
									return path;
								}
							break;
						}
					break;
				}
			}	innerWhile:_findclose(aDIR);
		}
	}
	return "";
}

#else
#	if defined(__ANDROID__)
#		define sPATHBEGIN "sdcard"
#	else
#		define sPATHBEGIN "."
#	endif
#	define IDXLIMIT 20

static inline string fileSystemSelector
(const fsSelector_selectType_t selectType = selectType_file, const char* usertip = nullptr)
{
	deque<string> dirs;
	deque<string> files;
	size_t idx;
	stack<size_t> selIdxs;
	stack<string> stkPaths;
	
	char keyInput;
#	if defined(__ANDROID__)
		string path(sSEP sPATHBEGIN);
#	else
		string path(sPATHBEGIN);
#	endif
	
	{
		stkPaths.push(sPATHBEGIN);
		size_t selectedIndex = 0;
		while(!stkPaths.empty())
		{
			DIR*	aDIR;//
			dirent*	aItem;//
			
			aDIR = opendir(path.c_str());//
					
			if(aDIR == NULL) return "";//
			
			dirs.clear();
			if(selectType != selectType_directory) files.clear();
			
			while((aItem = readdir(aDIR)) != nullptr)//
			{
				if(strcmp(aItem->d_name,  ".") && strcmp(aItem->d_name,  ".."))
				{
					if(aItem->d_type == 4)
						dirs.push_back(aItem->d_name);
					else if(aItem->d_type == 8) files.push_back(aItem->d_name);
				}
			}			
			
			sort(dirs.begin(), dirs.end());
			switch(selectType)
			{
				case selectType_directory:break;
				case selectType_file:case selectType_directory_and_file:
					sort(files.begin(), files.end());
				break;
			}
			
			size_t dirsCount	= dirs.size();
			size_t filesCount	= files.size();
			size_t indexesCount = dirsCount + filesCount;
			
			if(selectedIndex > indexesCount)
				selectedIndex = indexesCount - 1;
				
			while(true)
			{
				cls;
				logo();
				
				if(usertip != nullptr)
					cout<<usertip<<endl;
				else switch(selectType)
				{
					case selectType_directory:
						cout<<"Press Space Key to select current location:"<<endl;
					break;
					case selectType_file:
						cout<<"Select a file and press Space Key to confirm:"<<endl;
					break;
					case selectType_directory_and_file:
						cout<<"Select a directory or file and press Space Key to confirm:"<<endl;
					break;
				}
				
				idx = selectedIndex;
				if(selectedIndex < dirsCount) for
				(
					deque<string>::const_iterator i = dirs.begin() + selectedIndex;
					idx < selectedIndex + IDXLIMIT && i != dirs.end();
					++i, ++idx
				)
				{
					if(idx == selectedIndex)
					{
						cout<<backWhite("    <DIR> ");
						cout<<draw(*i, bgWhite);
						#if defined(__ANDROID__)
							cout<<draw(spc(57 - (*i).length()), bgWhite)<<endl;
						#else
							cout<<draw(spc(90 - (*i).length()), bgWhite)<<endl;
						#endif
					}	else cout<<"    <DIR> "<<*i<<endl;
				}
				
				if(selectType != selectType_directory  &&  selectedIndex < dirsCount + filesCount) for
				(
					deque<string>::const_iterator i = files.begin() + (selectedIndex > dirsCount?selectedIndex-dirsCount:0);
					idx < selectedIndex + IDXLIMIT && i != files.end();
					++i, ++idx
				)
				{
					if(idx == selectedIndex)
					{
						cout<<backWhite("    <FIL> ");
						cout<<draw(*i, bgWhite);
						#if defined(__ANDROID__)
							cout<<draw(spc(57 - (*i).length()), bgWhite)<<endl;
						#else
							cout<<draw(spc(90 - (*i).length()), bgWhite)<<endl;
						#endif
					}	else cout<<"    <FIL> "<<*i<<endl;
				}
				
				tip();
				
				switch(keyInput = getch())
				{
					case INDDW:/*case INDDW2:case INDDW3:*/
						if(selectedIndex+1 < indexesCount)
							++selectedIndex;
						else selectedIndex = 0;
					break;
					
					case INDUP:/*case INDUP2:case INDUP3:*/
						if(selectedIndex > 0)
							--selectedIndex;
						else selectedIndex = selectType == selectType_directory? dirsCount-1 : indexesCount-1;
					break;
					
					case INDLF:/*case INDLF2:case INDLF3:*/
						path = path.substr(0, path.length() - stkPaths.top().length() - 1);
						stkPaths.pop();
						
						if(!selIdxs.empty())
						{
							selectedIndex = selIdxs.top();
							selIdxs.pop();
						}	else selectedIndex = 0;
						goto innerWhile;
					break;
					
					case INDEN:case INDRG:/*case INDRG2:case INDRG3:*/case '\n':case '\r':
						if(selectedIndex < dirsCount)
						{
							stkPaths.push(*(dirs.begin() + selectedIndex));
							path = path + sSEP + stkPaths.top();
							selIdxs.push(selectedIndex);
							selectedIndex = 0;
							goto innerWhile;
						}
						else
						{
							path = path + sSEP + *(files.begin() + selectedIndex - dirsCount);
							closedir(aDIR);
							return path;
						}
					break;
					
					case ' ':
						switch(selectType)
						{
							case selectType_directory:
								closedir(aDIR);
								return path;
							break;
							case selectType_file:
								if(selectedIndex >= dirsCount)
								{
									path = path + sSEP + *(files.begin() + selectedIndex - dirsCount);
									closedir(aDIR);
									return path;
								}
								else
								{
									stkPaths.push(*(dirs.begin() + selectedIndex));
									path = path + sSEP + stkPaths.top();
									selIdxs.push(selectedIndex);
									selectedIndex = 0;
									goto innerWhile;
								}
							break;
							case selectType_directory_and_file:
								if(selectedIndex < dirsCount)
								{
									path = path + sSEP + *(dirs.begin() + selectedIndex);
									closedir(aDIR);
									return path;
								}
								else
								{
									path = path + sSEP + *(files.begin() + selectedIndex - dirsCount);
									closedir(aDIR);
									return path;
								}
							break;
						}
					break;
					default:
						if
						(
							(keyInput >= 'A' && keyInput <= 'Z') ||
							(keyInput >= 'a' && keyInput <= 'z') ||
							(keyInput >= '0' && keyInput <= '9') ||
							(keyInput == '_' || keyInput == '$' || keyInput == '.')
						) for 
						(
							size_t idx = selectedIndex; 
							(selectedIndex == 0? (idx+1 != indexesCount): (idx+1 != selectedIndex)); 
							idx+1 < (indexesCount)? ++idx: idx=0
						)
						{
							if(idx < dirsCount)
							{
								if((*(dirs.begin() + idx))[0] == keyInput)
								{
									if(idx != selectedIndex)
									{
										selectedIndex = idx;
										break;
									}
								}
							}
							else
							{
								if((*(files.begin() + idx - dirsCount))[0] == keyInput)
								{
									if(idx != selectedIndex)
									{
										selectedIndex = idx;
										break;
									}
								}
							}
						}
						
						
					break;
				}
			}	innerWhile:closedir(aDIR);//
		}
	}
	return "";
}
#endif

static inline void search(DirTable* nowAt, deque<pair<fileSystem_node*, string> >& listResult, fileSystem_node& temp, string atPath)
{	
	fileSystem_node* fndNode = NULL;
	if((fndNode = nowAt->list[temp]) != NULL)
		listResult.push_back(make_pair(fndNode, atPath));
	
	for
	(
		AATreeZ<fileSystem_node>::mid_iterator i = nowAt->list.mid_begin();
		i != nowAt->list.mid_end() && !i->type;
		++i
	)
	{
		if(!strcmp(i->name, temp.name))
			listResult.push_back(make_pair(&(*i), atPath));
		
		if(atPath != "/")
			search(i->data.table, listResult, temp, atPath + "/" + i->name);
		else search(i->data.table, listResult, temp, atPath + i->name);
	}
}
static inline void userOpreationInterface(OrzFile& orz, bool flag = false, const char* cdPath = nullptr, string selectedIndexName = "");
static inline void searchMenu(OrzFile& orz, DirTable* nowAt, string& sname, string& nowPath)
{
	deque<pair<fileSystem_node*, string> > listResult;
	fileSystem_node temp;
	temp.type = true;
	temp.name = const_cast<char*>(sname.c_str());
	
	search(nowAt, listResult, temp, nowPath=="/"? "/" : nowPath.substr(0, nowPath.length()-1));
	size_t selectedIndex = 0;
	size_t idx;
	char keyInput;
	while(true)
	{
		cls;
		logo();
		
		cout<<"Searching result:"<<endl;
		
		idx = 0;
		for
		(
			deque<pair<fileSystem_node*, string> >::const_iterator i = listResult.begin();
			i != listResult.end();
			++i, ++idx
		)
		{
			bool 			type = i->first->type;
			const char* 	name = i->first->name;
			const string&	path = i->second; 
			if(idx == selectedIndex)
			{
				if(type) cout<<backWhite("    <FIL> ");
				else	 cout<<backWhite("    <DIR> ");
				
				cout<<draw(name, bgWhite);
				#if defined(__ANDROID__)
					cout<<draw(spc(57-strlen(name)-path.length()), bgWhite);
				#else
					cout<<draw(spc(90-strlen(name)-path.length()), bgWhite);
				#endif
				cout<<draw(path, bgWhite)<<endl;
			}
			else
			{
				#if defined(__ANDROID__)
					if(type) cout<<"    <FIL> "<<name<<spc(57-strlen(name)-path.length())<<path<<endl;
					else	 cout<<"    <DIR> "<<name<<spc(57-strlen(name)-path.length())<<path<<endl;
				#else
					if(type) cout<<"    <FIL> "<<name<<spc(90-strlen(name)-path.length())<<path<<endl;
					else	 cout<<"    <DIR> "<<name<<spc(90-strlen(name)-path.length())<<path<<endl;
				#endif
			}
		}
		
		tip();
		
		switch(keyInput = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex+1 < listResult.size())
					++selectedIndex;
				else selectedIndex = 0;
			break;
			
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > 0)
					--selectedIndex;
				else selectedIndex = listResult.size()-1;
			break;
			
			case INDLF:case INDLF2:case INDLF3:
				return;
			break;
			
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':case ' ':
			{
				if(!listResult.empty())
				{
					const pair<fileSystem_node*, string>& p = *(listResult.begin() + selectedIndex);
					userOpreationInterface(orz, true, p.second.c_str(), p.first->name);
				}
			}
			break;
		}
	}
}

static inline int nodeOperationMenu
(
	OrzFile&			orz, 
	DirTable*			nowAt, 
	fileSystem_node*	selectedNode, 
	string&				rename_newName, 
	string&				currentInnerPath,
	DirTable*&			moveFrom,
	fileSystem_node*&	moveNode,
	fileSystem_node*&	copyNode
)
{
	//	ok				ok		ok		ok	 ok		ok		ok		ok
	//	6			8	5		7		3	 4		1		2		0
	//新建文件夹 查找 添加 查看目录树  移动 拷贝  重命名 删除文件 解压缩
	//-------------nowAt-------------  ---both--  -----selectedNode-----
	size_t selectedIndex = 0, indexesCount = 9, minIndex = 0;
	string unorzIndex;  
	string renameIndex; 
	string deleteIndex; 
	string moveOpIndex; 
	string copyOpIndex; 
	
	rename_newName = "";
	moveNode = copyNode = nullptr;
	moveFrom = nullptr;
	
	if(selectedNode != nullptr)
	{
		#if defined(__ANDROID__)
			unorzIndex  = string("    Unorz  the \"") + selectedNode->name + "\"" + spc(50 - strlen(selectedNode->name));
			renameIndex = string("    Rename the \"") + selectedNode->name + "\"" + spc(50 - strlen(selectedNode->name));
			deleteIndex = string("    Delete the \"") + selectedNode->name + "\"" + spc(50 - strlen(selectedNode->name));
			moveOpIndex = string("    Move   the \"") + selectedNode->name + "\"" + spc(50 - strlen(selectedNode->name));
			copyOpIndex = string("    Copy   the \"") + selectedNode->name + "\"" + spc(50 - strlen(selectedNode->name));
		#else
			unorzIndex  = string("    Unorz  the \"") + selectedNode->name + "\"" + spc(83 - strlen(selectedNode->name));
			renameIndex = string("    Rename the \"") + selectedNode->name + "\"" + spc(83 - strlen(selectedNode->name));
			deleteIndex = string("    Delete the \"") + selectedNode->name + "\"" + spc(83 - strlen(selectedNode->name));
			moveOpIndex = string("    Move   the \"") + selectedNode->name + "\"" + spc(83 - strlen(selectedNode->name));
			copyOpIndex = string("    Copy   the \"") + selectedNode->name + "\"" + spc(83 - strlen(selectedNode->name));
		#endif
	}	else minIndex = 5;

	selectedIndex = minIndex;
	
	char keyInput;
	
	while(true)
	{
		cls;
		logo();
		cout<<"Select a operation to do:"<<endl;
		
		if(selectedNode != nullptr)
		{
			if(selectedIndex == 0)
				cout<<draw(unorzIndex.c_str(), bgWhite)<<endl;
			else cout<<unorzIndex<<endl;
			
			if(selectedIndex == 1)
				cout<<draw(renameIndex.c_str(), bgWhite)<<endl;
			else cout<<renameIndex<<endl;
			
			if(selectedIndex == 2)
				cout<<draw(deleteIndex.c_str(), bgWhite)<<endl;
			else cout<<deleteIndex<<endl;
			
			if(selectedIndex == 3)
				cout<<draw(moveOpIndex.c_str(), bgWhite)<<endl;
			else cout<<moveOpIndex<<endl;
			
			if(selectedIndex == 4)
				cout<<draw(copyOpIndex.c_str(), bgWhite)<<endl;
			else cout<<copyOpIndex<<endl;
		}
		
		if(selectedIndex == 5)
		#if defined(__ANDROID__)
			cout<<backWhite("    Insert a File or Directory at current location                 ")<<endl;
		#else
			cout<<backWhite("    Insert a File or Directory at current location                                                  ")<<endl;
		#endif
		else cout<<"    Insert a File or Directory at current location"<<endl;
		
		if(selectedIndex == 6)
		#if defined(__ANDROID__)
			cout<<backWhite("    Create a Directory at current location                         ")<<endl;
		#else
			cout<<backWhite("    Create a Directory at current location                                                          ")<<endl;
		#endif
		else cout<<"    Create a Directory at current location"<<endl;
		
		if(selectedIndex == 7)
		#if defined(__ANDROID__)
			cout<<backWhite("    View all the files and directories in current location         ")<<endl;
		#else
			cout<<backWhite("    View all the files and directories in current location                                          ")<<endl;
		#endif
		else cout<<"    View all the files and directories in current location"<<endl;
		
		if(selectedIndex == 8)
		#if defined(__ANDROID__)
			cout<<backWhite("    Search in current location                                     ")<<endl;
		#else
			cout<<backWhite("    Search in current location                                                                      ")<<endl;
		#endif
		else cout<<"    Search in current location"<<endl;
		
		tip();
		
		switch(keyInput = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex+1 < indexesCount)
					++selectedIndex;
				else selectedIndex = minIndex;
			break;
			
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > minIndex)
					--selectedIndex;
				else selectedIndex = indexesCount-1;
			break;
			
			case INDLF:case INDLF2:case INDLF3:
				return 0;
			break;
			
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':case ' ':
				switch(selectedIndex)
				{
					case 0:
					{
						string path = fileSystemSelector(selectType_directory);
						if(path != "")
						{
							cls;
							logo();
							OrzFile::unorz(selectedNode, path.c_str());
							whiteLine();
							cout<<green("File(s) unorzed successfully. Press Enter Key to continue...");
							cin.get();
						}
					}
					break;
					case 1:
					{
						string newName(reNameMenu());
						if(newName != "")
						{
							OrzFile::rename(selectedNode, nowAt, newName.c_str());
							rename_newName = newName;
							return -1;
						}
					}
					break;
					case 2:
						if(makeUserSure("delete", selectedNode->name))
						{
							nowAt->remove(selectedNode);
							return -1;
						}
					break;
					case 3:
						moveFrom = nowAt;
						moveNode = selectedNode;
						copyNode = nullptr;
						return 0;
					break;
					case 4:
						moveFrom = nullptr;
						copyNode = selectedNode;
						moveNode = nullptr;
						return 0;
					break;
					case 5:
					{
						string path = fileSystemSelector(selectType_directory_and_file);
						if(path != "")
						{
							cls;
							logo();
							orz.add(path.c_str(), (currentInnerPath=="/"? "/" : currentInnerPath.substr(0, currentInnerPath.length()-1)).c_str());
							rename_newName = getFileName(path.c_str());
							whiteLine();
							cout<<green("File(s) orzed successfully. Press Enter Key to continue...");
							cin.get();
							return -1;
						}
					}
					break;
					case 6:
					{
						string newName(reNameMenu());
						if(newName != "")
						{
							DirTable::createFloader(nowAt, newName.c_str());
							rename_newName = newName;
							return -1;
						}
					}
					break;
					case 7:
						viewAll(nowAt);
					break;
					case 8:
					{
						string searchName(reNameMenu("Please input the name to search:"));
						if(searchName != "")
							searchMenu(orz, nowAt, searchName, currentInnerPath);
					}
					break;
				}
			break;
		}
	}
} 

static inline void userOpreationInterface(OrzFile& orz, bool flag, const char* cdPath, string selectedIndexName)
{
	stack<size_t> 			indexes;
	deque<fileSystem_node*> userList;
	DirTable				*nowAt		= &orz.userIndex;
	DirTable				*back		= nowAt->getBack();
	
	DirTable				*moveFrom	= nullptr;
	fileSystem_node			*moveNode	= nullptr;
	fileSystem_node		 	*copyNode 	= nullptr;
	
	char c = '\0';
	
	nowAt->getView(userList);
	string newName(selectedIndexName);
	
	string innerPathTrace("/");
	stack<string> stkPaths;
	
	size_t selectedIndex = 0;
	size_t idx = 0;
	
	
	if(cdPath != nullptr)
	{
		size_t n;
		fileSystem_node temp;
		fileSystem_node* foundNode = NULL;
		temp.type = false;
		
		for
		(
			const char* reader = cdPath + 1;
			*reader != '\0';
		)
		{
			n = 0;
			while(reader[n] != '/' && reader[n] != '\0')
				++n;
			
			temp.name = strncpy(new char[n+1], reader, n);
			temp.name[n] = '\0';
			
			if((foundNode = nowAt->list[temp]) != NULL)
			{
				back			= nowAt;
				nowAt			= foundNode->data.table;
				selectedIndex	= 0;
				
				stkPaths.push(foundNode->name);
				innerPathTrace = innerPathTrace + foundNode->name + '/';
			}
			
			delete temp.name;
			
			reader += n;
			if(*reader == '/')
				++reader;
		}
		nowAt->getView(userList);
	}
	
	while(true)
	{
		cls;
		logo();
		cout<<"Current location:"<<(innerPathTrace=="/"? "/" : innerPathTrace.substr(0, innerPathTrace.length()-1))<<endl;
		
		if(moveNode != nullptr)
			cout<<cyan("Select a location and press space key to move here:")<<endl;
		else if(copyNode != nullptr)
			cout<<cyan("Select a location and press space key to copy here:")<<endl;
		else cout<<"Select a item and press space key to check operations menu:"<<endl;
		
		idx = 0;
		if(newName != "")
			selectedIndex = userList.size();
		else if(selectedIndex > userList.size())
			selectedIndex = userList.size() - 1;
		for
		(
			deque<fileSystem_node*>::const_iterator i = userList.begin();
			i != userList.end();
			++i, ++idx
		)
		{
			if(newName!="" && !strcmp(newName.c_str(), (*i)->name))
			{
				selectedIndex = idx;
				newName = "";
			}
			
			if((*i)->type)
			{		//file
				if(idx!=selectedIndex)
				{
					#if defined(__ANDROID__)
					cout<<"    <FIL> "<<left<<setw(57)<<(*i)->name<<endl
						<<right<<setw(29)<<(((*i)->data.element->bitSize==0)? 0: upDiv((*i)->data.element->bitSize, (uint64_t)8))
						<<" / "
						<<left<<setw(29)<<(*i)->data.element->sourceFileByteSize
						<<" Bytes"<<endl;
					#else
					cout<<"    <FIL> "<<left<<setw(32)<<(*i)->name
						<<right<<setw(24)<<(((*i)->data.element->bitSize==0)? 0: upDiv((*i)->data.element->bitSize, (uint64_t)8))
						<<" / "
						<<left<<setw(24)<<(*i)->data.element->sourceFileByteSize
						<<"  Bytes"<<endl;
					#endif
				}
				else
				{
					string aLine("");
					string orzedSize(toString((((*i)->data.element->bitSize==0)? 0: upDiv((*i)->data.element->bitSize, (uint64_t)8))));
					string sourceFileSize(toString((*i)->data.element->sourceFileByteSize).c_str());
					#if defined(__ANDROID__)
					aLine = aLine + "    <FIL> " + (*i)->name + spc(57-strlen((*i)->name)) + '\n' +
							spc(29-orzedSize.length()) + orzedSize + " / " + sourceFileSize +
							spc(29-sourceFileSize.length()) + " Bytes";
					#else
					aLine = aLine + "    <FIL> " + (*i)->name + spc(32-strlen((*i)->name)) + 
							spc(24-orzedSize.length()) + orzedSize + " / " + sourceFileSize +
							spc(24-sourceFileSize.length()) + "  Bytes";
					#endif
					cout<<draw(aLine, bgWhite)<<endl;
				}
			}
			else	//floader
			{
				if(idx != selectedIndex)
				{
					#if defined(__ANDROID__)
						cout<<"    <DIR> "<<left<<setw(57)<<(*i)->name<<endl;
					#else
						cout<<"    <DIR> "<<left<<setw(90)<<(*i)->name<<endl;
					#endif
				}
				else
				{
					cout<<backWhite("    <DIR> ");
					cout<<draw((*i)->name, bgWhite);
					#if defined(__ANDROID__)
						cout<<draw(spc(57-strlen((*i)->name)), bgWhite)<<endl;
					#else
						cout<<draw(spc(90-strlen((*i)->name)), bgWhite)<<endl;
					#endif
				}
			}
		}
		
		tip();
		
		switch(c = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex+1 < userList.size())
					++selectedIndex;
				else selectedIndex = 0;
			break;
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > 0)
					--selectedIndex;
				else selectedIndex = userList.size()-1;
			break;
			case INDLF:case INDLF2:case INDLF3:
				if(back != nullptr)
				{
					nowAt			= back;
					back			= nowAt->getBack();
					if(!indexes.empty())
					{
						selectedIndex = indexes.top();
						indexes.pop();
					}	else selectedIndex = 0;
					
					nowAt->getView(userList);
					
					if(!stkPaths.empty())
					{
						innerPathTrace = innerPathTrace.substr(0, innerPathTrace.length()-stkPaths.top().length()-1);
						stkPaths.pop();
					}
				}
				else
				{
					if(moveNode!=nullptr || copyNode!=nullptr)
					{
						moveNode = copyNode = nullptr;
						moveFrom = nullptr;
					}
					else if(!flag)
					{
						switch(makeUserSure_Triple("save & exit"))
						{
							case cancel:break;
							case yes:
								if(orz.openedByOrzFilePath != nullptr)
								{
									orz.dump(orz.openedByOrzFilePath);
									return;
								}
								else
								{
									string path = fileSystemSelector(selectType_directory);
									if(path != "")
									{
										string newName(reNameMenu("Name the new orz file just selected to save -"));
										if(newName != "")
										{
											newName = path + sSEP + newName;
											const char* fileNamePostfix = getFileNamePostfix(newName.c_str());
											if(fileNamePostfix==NULL || stricmp(fileNamePostfix, "orz"))
												newName += ".orz";
											orz.dump(newName.c_str());
											return;
										}
									}
								}
							break;
							case no:return;
						}
					}	else return;
				}
			break;
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':
			{
				if(userList.size() > 0)
				{
					fileSystem_node* selectedNode = *(userList.begin() + selectedIndex);
					
					if(selectedNode->type && moveNode==nullptr && copyNode==nullptr)
						goto opt;
					else
					{
						back			= nowAt;
						nowAt			= selectedNode->data.table;
						indexes.push(selectedIndex);
						selectedIndex	= 0;
						nowAt->getView(userList);
						
						stkPaths.push(selectedNode->name);
						innerPathTrace = innerPathTrace + selectedNode->name + '/';
					}
				}	else if(moveNode==nullptr && copyNode==nullptr) goto opt;
			}
			break;
			case ' ':opt:
			{
				if(moveNode != nullptr)
				{
					fileSystem_node temp(*moveNode);
					//temp.depth = nowAt->depth;
					if(nowAt->list.insert(temp) == NULL)
					{
						moveFrom->list.del(*moveNode);
						newName = temp.name;
						nowAt->getView(userList);
						if(!temp.type)
							temp.data.table->father = nowAt;
						//OrzFile::reset_depth(nowAt, temp);
					}
					else
					{
						cls;
						logo();
						cout<<endl<<endl<<endl;
						cout<<yellow("    An item that name same as choosed has been existed.")<<endl<<endl<<endl;
						whiteLine();
						cout<<"Press Enter Key to continue...";
						cin.get();
					}
					
					moveNode = copyNode = nullptr;
					moveFrom = nullptr;
				}
				else if(copyNode != nullptr)
				{
					fileSystem_node temp(*copyNode);
					//temp.depth = nowAt->depth;
					temp.name = strcpy(new char[strlen(temp.name)+1], temp.name);
					if(temp.type)
						temp.data.element = new FileSystemInfoBlock;
					else temp.data.table = new DirTable;
					
					if(nowAt->list.insert(temp) == NULL)
					{
						if(temp.type)
							OrzFile::copyFile(copyNode->data.element, temp.data.element);
						else
						{
							OrzFile::copyFloader(copyNode->data.table, temp.data.table/*, nowAt->depth*/);
							temp.data.table->father = nowAt;
						}
						
						newName = temp.name;
						nowAt->getView(userList);
					}
					else
					{
						delete temp.name;
						if(temp.type)
							delete temp.data.element;
						else delete temp.data.table;
						
						cls;
						logo();
						cout<<endl<<endl<<endl;
						cout<<yellow("    An item that name same as choosed has been existed.")<<endl<<endl<<endl;
						whiteLine();
						cout<<"Press Enter Key to continue...";
						cin.get();
					}
					
					moveNode = copyNode = nullptr;
					moveFrom = nullptr;
				}
				else
				{
					int returnValue = nodeOperationMenu
					(
						orz,
						nowAt, userList.size() == 0	? 
							nullptr					:
							*(userList.begin() + selectedIndex)
						, 
						newName, 
						innerPathTrace,
						moveFrom,
						moveNode,
						copyNode
					);
					
					if(returnValue != 0)
					{
						nowAt->getView(userList);
						
						if(returnValue > 0)
							selectedIndex += returnValue;
						
						if(selectedIndex+1 > userList.size())
							selectedIndex = userList.size()-1;
					}
				}
			}
			break;
		}
	}
}


static inline bool firstScreen(void)
{
	size_t selectedIndex = 0;
	char keyInput;
	
	while(true)
	{
		cls;
		logo();
		
		cout<<endl;
		
		if(selectedIndex == 0)
		#if defined(__ANDROID__)
			cout<<backWhite("    Create a new empty orz file                                    ")<<endl;	
		#else
			cout<<backWhite("    Create a new empty orz file                                                                     ")<<endl;
		#endif
		else          cout<<"    Create a new empty orz file"<<endl;
		
		if(selectedIndex == 1)
		#if defined(__ANDROID__)
			cout<<backWhite("    Open a exist orz file                                          ")<<endl;
		#else
			cout<<backWhite("    Open a exist orz file                                                                           ")<<endl;
		#endif
		else          cout<<"    Open a exist orz file"<<endl;
		
		tip();
		
		switch(keyInput = getch())
		{
			case INDDW:case INDDW2:case INDDW3:
				if(selectedIndex < 1)
					++selectedIndex;
				else selectedIndex = 0;
			break;
			
			case INDLF:
				if(makeUserSure("exit"))
				{
					cls;
					exit(0);
				}
			break;
			
			case INDUP:case INDUP2:case INDUP3:
				if(selectedIndex > 0)
					--selectedIndex;
				else selectedIndex = 1;
			break;
			
			case INDEN:case INDRG:case INDRG2:case INDRG3:case '\n':case '\r':case ' ':
				return selectedIndex==1? true : false;
			break;
		}
	}
}

int main(int argc, char *argv[])
{
	bool loop = false;
	while(true)
	{
		OrzFile orz;
		logo();
	
		if(argc==2 && stricmp(getFileNamePostfix(argv[1]), "orz")==0)
		{
			orz.open(argv[1]);
		}
		else if(argc > 1)
		{
			cout<<"Orzing starting..."<<endl;
			for(int i=1 ; i<argc ; ++i)
				orz.add(argv[i], "/");
		
			whiteLine();
			cout<<green("File(s) orzed successfully. Press Enter Key to continue...");
			
			cin.get();
		}
		else if((loop=true, firstScreen()))
		{
			string sFile;
			
			#if defined(__ANDROID__)
				sFile = fileSystemSelector(selectType_file, "Select a Orz file and press space key to open it, \nyou can also press \"4\" or \"A\" to create a new Orz file.");
			#else
				sFile = fileSystemSelector(selectType_file);
			#endif
			if(sFile != "")
				orz.open(sFile.c_str());
			else continue;
		}
		userOpreationInterface(orz);
		if(!loop) break;
	}
	cls;
	return 0;
}
